package com.gupaoedu.vip.netty.io.bio.tomcat;

import com.gupaoedu.vip.netty.io.bio.tomcat.http.GPRequest;
import com.gupaoedu.vip.netty.io.bio.tomcat.http.GPResponse;
import com.gupaoedu.vip.netty.io.bio.tomcat.http.GPServlet;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @program:gupaoedu-vip-netty-io
 * @description:简单的tomcat示例
 * @author:Gongchao
 * @date:2020-04-26
 **/
public class GPTomcat {

    //J2EE标准
    //Servlet
    //Request
    //Response

    //1.配置启动端口，默认8080  ServerSocket ip:localhost
    //2.配置web.xml  自己写的Servlet继承HttpServlet
    //  servlet-name
    //  servlet-class
    //  url-pattern
    //3.读取配置，将urlpattern和Servlet建立映射关系
    //  Map  servletMapping
    //4.Http请求，发送的数据就是字符串，有一定的规则（Http协议）
    //5.从协议内容中获取url，把相应的Servlet用反射进行实例化
    //6.调用实例化对象的service方法，执行具体的逻辑doGet/doPost方法
    //7.Request(InputStream)/Response(OutputStream)

    private int port = 8080;

    private ServerSocket serverSocket;

    private Map<String, GPServlet> servletMap = new HashMap<String,GPServlet>();

    private Properties webxml = new Properties();

    /* *
     * @description:加载web.xml，同时初始化ServletMapping 对象
     * @author:Gongchao
     * @date:2020-四月-26
     * @param:[]
     * @return:void
     */
    private void init() {
        String WEB_INF = this.getClass().getResource("/").getPath();
        try {
            FileInputStream fileInputStream = new FileInputStream(WEB_INF+"web.properties");
            webxml.load(fileInputStream);

            for(Object k : webxml.keySet()) {
                String key = k.toString();
                if(key.endsWith(".url")){
                    String servletName = key.replaceAll("\\.url$","");
                    String url = webxml.getProperty(key);
                    String className = webxml.getProperty(servletName+".className");
                    //单实例，多线程
                    GPServlet gpServlet = (GPServlet) Class.forName(className).newInstance();
                    servletMap.put(url,gpServlet);

                }

            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    private void process(Socket client) throws Exception {
        InputStream inputStream = client.getInputStream();
        OutputStream outputStream = client.getOutputStream();

        GPRequest gpRequest = new GPRequest(inputStream);
        GPResponse gpResponse = new GPResponse(outputStream);

        String url = gpRequest.getUrl();
        if(servletMap.containsKey(url)) {
            servletMap.get(url).service(gpRequest,gpResponse);
        }else {
            gpResponse.write("404 - Not Found");
        }

        outputStream.flush();
        outputStream.close();

        inputStream.close();
        client.close();
    }

    /* *
     * @description:启动方法
     * @author:Gongchao
     * @date:2020-四月-26
     * @param:[]
     * @return:void
     */
    private void start() {
        //加载配置文件，初始化ServletMappint
        init();

        try {
            serverSocket = new ServerSocket(this.port);
            System.out.println("GP Tomcat 已启动，监听的端口是："+this.port);

            //等待用户请求，用一个死循环来等待用户请求
            while(true) {
                Socket socket = serverSocket.accept();
                process(socket);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new GPTomcat().start();
    }
}
